package BancoDeDados;

import Biblioteca.ConexaoSSH;
import Biblioteca.VerificacaoErros;
import com.jcraft.jsch.JSchException;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 * ConexaoMySQL
 *
 * Versao 1.0
 *
 * Data Criação 28/01/2014
 *
 * @author Igor
 */
public class ConexaoMySQL implements ConexaoBD {

    //Atributos
    private static ConexaoMySQL uniqueInstance;
    private Connection con = null;
    private Statement stm = null;
    private String driver = "";
    private Path directoryDB;
    private String arquivo;
    private String url = "";
    private String userNameDB = "";
    private String passwordDB = "";

    //Construtores
    private ConexaoMySQL() {
        this.gerenciarConfiguracoes();

        try {
            // Carregando o JDBC Driver padrão
            Class.forName(this.driver);
            this.con = DriverManager.getConnection(this.url, this.userNameDB, this.passwordDB);

        } catch (Exception e) {  //Driver não encontrado
            JOptionPane.showMessageDialog(null, VerificacaoErros.retornaMensagemErro(e), "Erro!", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
    }

    //Getters e Setters
    @Override
    public Connection getCon() {
        return con;
    }

    @Override
    public void setCon(Connection con) {
        this.con = con;
    }

    @Override
    public Statement getStm() {
        return stm;
    }

    @Override
    public void setStm(Statement stm) {
        this.stm = stm;
    }

    //Outros metodos
    @Override
    public void gerenciarConfiguracoes() {
        Properties config = new Properties();
        String arquivoProperties = "./configTREF.properties";
        try {
            config.load(new FileInputStream(arquivoProperties));
        } catch (IOException ex) {
            Logger.getLogger(ConexaoMySQL.class.getName()).log(Level.SEVERE, null, ex);
        }

        String porta = config.getProperty("MySQL_porta");
        String ipServidor = config.getProperty("MySQL_ipServidor");
        String arquivoBD = config.getProperty("MySQL_baconDeDados");
        String userName = config.getProperty("MySQL_userName");
        String password = config.getProperty("MySQL_password");

        this.driver = "com.mysql.jdbc.Driver";
        // Configurando a nossa conexão com um banco de dados//
        this.arquivo = arquivoBD;        //nome do seu banco de dados
        this.url = "jdbc:mysql://" + ipServidor + ":" + porta + "/" + this.arquivo;
        this.userNameDB = userName;        //nome de um usuário de seu BD      
        this.passwordDB = password;      //sua senha de acesso


        if (config.getProperty("SSH_conexao").equals("true")) {
            try {
                int sshPortBindTunel = Integer.parseInt(config.getProperty("SSH_localPortBindTunel"));
                ConexaoSSH.doSshTunnel(config.getProperty("SSH_userName"),
                        config.getProperty("SSH_password"),
                        config.getProperty("SSH_host"),
                        Integer.parseInt(config.getProperty("SSH_port")),
                        ipServidor,
                        sshPortBindTunel,
                        Integer.parseInt(porta));

                this.url = "jdbc:mysql://" + ipServidor + ":" + sshPortBindTunel + "/" + this.arquivo;
            } catch (JSchException e) {
                JOptionPane.showMessageDialog(null, VerificacaoErros.retornaMensagemErro(e), "Erro!", JOptionPane.ERROR_MESSAGE);
                System.exit(0);
            }
        }
    }

    @Override
    public void startDB() throws Exception {
        try {
            setStm(getCon().createStatement());
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    @Override
    public void stopDB() throws Exception {
        try {
            getStm().close();
        } catch (Exception e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    @Override
    public void restartDB() throws Exception {
        stopDB();
        startDB();
    }

    
    public static synchronized ConexaoMySQL getInstance(){
        if (uniqueInstance == null) {
            uniqueInstance = new ConexaoMySQL();
        }
        return uniqueInstance;
    }
}
